<template>
  <div class="data-structure-visualizer">
    <div class="header">
      <h3>{{ title }}</h3>
      <div class="controls">
        <el-button-group>
          <el-button type="primary" @click="addElement" :disabled="!canAdd">
            添加元素
          </el-button>
          <el-button type="danger" @click="removeElement" :disabled="!canRemove">
            删除元素
          </el-button>
          <el-button @click="reset">
            重置
          </el-button>
        </el-button-group>
      </div>
    </div>

    <div class="visualization-container" ref="container">
      <!-- 数组可视化 -->
      <div v-if="type === 'array'" class="array-visualization">
        <div class="array-elements">
          <div v-for="(element, index) in elements" 
               :key="index" 
               class="array-element"
               :class="{ 'highlight': highlightedIndices.includes(index) }">
            <div class="element-value">{{ element }}</div>
            <div class="element-index">{{ index }}</div>
          </div>
        </div>
      </div>

      <!-- 邻接矩阵可视化 -->
      <div v-if="type === 'adjacencyMatrix'" class="matrix-visualization">
        <div class="matrix-controls">
          <el-input-number v-model="vertexCount" :min="2" :max="8" size="small" label="节点数量" @change="initMatrix" />
          <el-switch v-model="isDirected" active-text="有向图" inactive-text="无向图" @change="updateMatrixType" />
          <el-switch v-model="isWeighted" active-text="带权图" inactive-text="无权图" @change="updateMatrixType" />
        </div>
        
        <div class="graph-view">
          <div class="vertex-container">
            <div 
              v-for="i in vertexCount" 
              :key="`vertex-${i}`"
              class="vertex"
              :class="{ 'highlight': highlightedVertices.includes(i-1) }"
              :style="{ 
                left: `${Math.cos(2 * Math.PI * (i-1) / vertexCount - Math.PI/2) * 120 + 150}px`,
                top: `${Math.sin(2 * Math.PI * (i-1) / vertexCount - Math.PI/2) * 120 + 150}px`
              }"
            >
              {{ i-1 }}
            </div>
            
            <svg width="300" height="300" class="edges">
              <defs v-if="isDirected">
                <marker 
                  id="arrowhead" 
                  markerWidth="10" 
                  markerHeight="7" 
                  refX="9" 
                  refY="3.5" 
                  orient="auto"
                >
                  <polygon points="0 0, 10 3.5, 0 7" fill="#409eff" />
                </marker>
              </defs>
              
              <line 
                v-for="edge in edges" 
                :key="`edge-${edge.from}-${edge.to}`"
                :x1="edge.x1" 
                :y1="edge.y1" 
                :x2="edge.x2" 
                :y2="edge.y2"
                stroke="#409eff"
                stroke-width="2"
                :marker-end="isDirected ? 'url(#arrowhead)' : ''"
              />
            </svg>
          </div>
          
          <div class="matrix-container">
            <table class="matrix-table">
              <thead>
                <tr>
                  <th></th>
                  <th v-for="i in vertexCount" :key="`head-${i}`">{{ i-1 }}</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="i in vertexCount" :key="`row-${i}`">
                  <th>{{ i-1 }}</th>
                  <td 
                    v-for="j in vertexCount" 
                    :key="`cell-${i}-${j}`"
                    :class="{ 
                      'highlight': highlightedCells.includes(`${i-1}-${j-1}`),
                      'diagonal': i-1 === j-1 && !isDirected,
                      'has-value': matrix && matrix.length && matrix[i-1] && matrix[i-1][j-1] === 1
                    }"
                    @click="toggleEdge(i-1, j-1)"
                  >
                    {{ matrix && matrix.length && matrix[i-1] && matrix[i-1][j-1] ? matrix[i-1][j-1] : 0 }}
                  </td>
                </tr>
              </tbody>
            </table>
            <div class="help-text">点击单元格切换边的存在（1表示有边，0表示无边）</div>
          </div>
        </div>
      </div>

      <!-- 邻接表可视化 -->
      <div v-if="type === 'adjacencyList'" class="list-visualization">
        <div class="list-controls">
          <el-input-number v-model="vertexCount" :min="2" :max="8" size="small" label="节点数量" @change="initAdjList" />
          <el-switch v-model="isDirected" active-text="有向图" inactive-text="无向图" @change="updateListType" />
          <el-switch v-model="isWeighted" active-text="带权图" inactive-text="无权图" @change="updateListType" />
        </div>
        
        <div class="graph-view">
          <div class="vertex-container">
            <div 
              v-for="i in vertexCount" 
              :key="`vertex-${i}`"
              class="vertex"
              :class="{ 'highlight': highlightedVertices.includes(i-1) }"
              :style="{ 
                left: `${Math.cos(2 * Math.PI * (i-1) / vertexCount - Math.PI/2) * 120 + 150}px`,
                top: `${Math.sin(2 * Math.PI * (i-1) / vertexCount - Math.PI/2) * 120 + 150}px`
              }"
            >
              {{ i-1 }}
            </div>
            
            <svg width="300" height="300" class="edges">
              <!-- 为有向图添加箭头标记 -->
              <defs v-if="isDirected">
                <marker 
                  id="arrowhead-list" 
                  markerWidth="10" 
                  markerHeight="7" 
                  refX="9" 
                  refY="3.5" 
                  orient="auto"
                >
                  <polygon points="0 0, 10 3.5, 0 7" fill="#409eff" />
                </marker>
              </defs>
              
              <!-- 自环用路径渲染 -->
              <path 
                v-for="(edge, index) in edges.filter(e => e && e.isLoop)" 
                :key="`loop-${index}`"
                :d="edge.path"
                :class="{ 'highlighted-edge': highlightedEdges.includes(index) }"
                stroke="#409eff"
                stroke-width="2"
                fill="none"
                :marker-end="isDirected ? 'url(#arrowhead-list)' : ''"
              />
              
              <line 
                v-for="(edge, index) in edges.filter(e => e && !e.isLoop)" 
                :key="`edge-${index}`"
                :x1="edge.x1" 
                :y1="edge.y1" 
                :x2="edge.x2" 
                :y2="edge.y2"
                :class="{ 'highlighted-edge': highlightedEdges.includes(index) }"
                stroke="#409eff"
                stroke-width="2"
                :marker-end="isDirected ? 'url(#arrowhead-list)' : ''"
              />
              
              <text 
                v-if="isWeighted"
                v-for="(edge, index) in edges.filter(e => e)" 
                :key="`weight-${index}`"
                :x="edge.isLoop ? edge.x1 + 30 : (edge.x1 + edge.x2) / 2 + 5" 
                :y="edge.isLoop ? edge.y1 - 20 : (edge.y1 + edge.y2) / 2 - 5"
                fill="#f56c6c"
                font-size="14"
              >
                {{ edge.weight }}
              </text>
            </svg>
          </div>
          
          <div class="adj-list-container">
            <div 
              v-for="(list, vertexIndex) in adjList" 
              :key="`list-${vertexIndex}`" 
              class="adj-list-row"
              :class="{ 'highlight-row': highlightedVertices.includes(vertexIndex) }"
            >
              <div class="vertex-label">{{ vertexIndex }} →</div>
              <div class="adj-vertices">
                <div 
                  v-for="(edge, edgeIndex) in list" 
                  :key="`edge-${vertexIndex}-${edgeIndex}`"
                  class="adj-vertex"
                  :class="{ 'highlight': highlightedEdges.includes(getEdgeIndexFromAdjList(vertexIndex, edge.vertex)) }"
                  @click="toggleAdjListEdge(vertexIndex, edge.vertex)"
                >
                  {{ edge.vertex }}{{ isWeighted ? ` (${edge.weight})` : '' }}
                </div>
                <el-button 
                  size="small" 
                  @click="showAddEdgeDialog(vertexIndex)"
                  class="add-edge-btn"
                >
                  添加
                </el-button>
              </div>
            </div>
            <div class="help-text">点击节点添加/删除边</div>
          </div>
        </div>
      </div>

      <!-- 链表可视化 -->
      <div v-if="type === 'linkedList'" class="linked-list-visualization">
        <div class="list-elements">
          <div v-for="(element, index) in elements" 
               :key="index" 
               class="list-node"
               :class="{ 'highlight': highlightedIndices.includes(index) }">
            <div class="node-value">{{ element }}</div>
            <div class="node-pointer" v-if="index < elements.length - 1">→</div>
          </div>
        </div>
      </div>

      <!-- 二叉树可视化 -->
      <div v-if="type === 'binaryTree'" class="binary-tree-visualization">
        <div ref="treeContainer" class="tree-container">
          <!-- 连接线 -->
          <svg class="tree-connections" :width="treeContainerWidth" :height="treeContainerHeight">
            <path
              v-for="(connection, index) in treeConnections"
              :key="`connection-${index}`"
              :d="connection"
              stroke="#409eff"
              stroke-width="2"
              fill="none"
            />
          </svg>
          
          <!-- 节点 -->
          <div 
            v-for="(node, index) in flattenedTreeNodes" 
            :key="`node-${index}`"
            class="tree-node"
            :class="{ 'highlight': highlightedIndices.includes(index), 'empty-node': node.value === null }"
            :style="{
              visibility: node.value === null ? 'hidden' : 'visible',
              left: `${node.x - NODE_SIZE/2}px`,
              top: `${node.y - NODE_SIZE/2}px`
            }"
          >
            {{ node.value !== null ? node.value : '' }}
          </div>
        </div>
      </div>

      <!-- 栈可视化 -->
      <div v-if="type === 'stack'" class="stack-visualization">
        <div class="stack-elements">
          <div v-for="(element, index) in elements.slice().reverse()" 
               :key="index" 
               class="stack-element"
               :class="{ 'highlight': highlightedIndices.includes(elements.length - 1 - index) }">
            {{ element }}
          </div>
        </div>
        <div class="stack-pointer">← top</div>
      </div>

      <!-- 队列可视化 -->
      <div v-if="type === 'queue'" class="queue-visualization">
        <div class="queue-elements">
          <div v-for="(element, index) in elements" 
               :key="index" 
               class="queue-element"
               :class="{ 'highlight': highlightedIndices.includes(index) }">
            {{ element }}
          </div>
        </div>
        <div class="queue-pointers">
          <div class="front-pointer">front →</div>
          <div class="rear-pointer">← rear</div>
        </div>
      </div>
    </div>

    <!-- 添加边对话框 -->
    <el-dialog
      v-model="addEdgeDialogVisible"
      title="添加边"
      width="30%"
      append-to-body
    >
      <el-form :model="newEdge" label-width="80px">
        <el-form-item label="起点">
          <el-tag>节点 {{ newEdge.from }}</el-tag>
        </el-form-item>
        <el-form-item label="目标节点">
          <el-select v-model="newEdge.to" placeholder="选择目标节点">
            <el-option 
              v-for="i in vertexCount" 
              :key="i-1" 
              :label="`节点 ${i-1}`" 
              :value="i-1"
              :disabled="!isDirected && newEdge.from === i-1"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="isWeighted" label="权重">
          <el-input-number v-model="newEdge.weight" :min="1" :max="9" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="addEdgeDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="addEdge">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick, watch, watchEffect, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'

const props = defineProps({
  type: {
    type: String,
    required: true,
    default: 'array'
  },
  maxSize: {
    type: Number,
    default: 10
  }
})

// 初始化所有状态变量
const elements = ref([])
const highlightedIndices = ref([])
const container = ref(null)

// 树的配置
const NODE_SIZE = 40
const LEVEL_GAP = 70
const HORIZONTAL_SPACING = 50
const treeContainer = ref(null)
const treeContainerWidth = ref(0)
const treeContainerHeight = ref(0)

// 扁平化的树节点数组，用于绝对定位
const flattenedTreeNodes = ref([])

// 树的连接线
const treeConnections = ref([])

// 图数据结构特有的状态
const vertexCount = ref(5)
const isDirected = ref(false)
const isWeighted = ref(true)
const matrix = ref([])
const adjList = ref([])
const edges = ref([])
const highlightedVertices = ref([])
const highlightedEdges = ref([])
const highlightedCells = ref([])

// 添加边对话框
const addEdgeDialogVisible = ref(false)
const newEdge = ref({
  from: 0,
  to: 0,
  weight: 1
})

// 初始化组件内部数据
ensureArraysInitialized()

const title = computed(() => {
  const titles = {
    array: '数组可视化',
    linkedList: '链表可视化',
    binaryTree: '二叉树可视化',
    stack: '栈可视化',
    queue: '队列可视化',
    adjacencyMatrix: '邻接矩阵可视化',
    adjacencyList: '邻接表可视化',
    heap: '堆可视化'
  }
  return titles[props.type] || '数据结构可视化'
})

// 计算属性
const canAdd = computed(() => elements.value && elements.value.length < props.maxSize)
const canRemove = computed(() => elements.value && elements.value.length > 0)

// 在组件创建时确保所有数组被初始化
function ensureArraysInitialized() {
  if (!matrix.value || !Array.isArray(matrix.value)) {
    matrix.value = Array(vertexCount.value).fill().map(() => Array(vertexCount.value).fill(0))
  }
  
  if (!adjList.value || !Array.isArray(adjList.value)) {
    adjList.value = Array(vertexCount.value).fill().map(() => [])
  }
  
  if (!edges.value || !Array.isArray(edges.value)) {
    edges.value = []
  }
  
  if (!elements.value || !Array.isArray(elements.value)) {
    elements.value = []
  }
  
  if (!highlightedIndices.value || !Array.isArray(highlightedIndices.value)) {
    highlightedIndices.value = []
  }
  
  if (!highlightedVertices.value || !Array.isArray(highlightedVertices.value)) {
    highlightedVertices.value = []
  }
  
  if (!highlightedEdges.value || !Array.isArray(highlightedEdges.value)) {
    highlightedEdges.value = []
  }
  
  if (!highlightedCells.value || !Array.isArray(highlightedCells.value)) {
    highlightedCells.value = []
  }
  
  if (!flattenedTreeNodes.value || !Array.isArray(flattenedTreeNodes.value)) {
    flattenedTreeNodes.value = []
  }
  
  if (!treeConnections.value || !Array.isArray(treeConnections.value)) {
    treeConnections.value = []
  }
}

// 重置所有状态
const resetAllStates = () => {
  // 重置通用状态
  elements.value = []
  highlightedIndices.value = []
  
  // 重置图状态
  edges.value = []
  highlightedVertices.value = []
  highlightedEdges.value = []
  highlightedCells.value = []
  
  // 重置矩阵状态 - 使用空矩阵而不是null
  matrix.value = Array(vertexCount.value).fill().map(() => Array(vertexCount.value).fill(0))
  
  // 重置邻接表状态 - 使用空邻接表而不是null
  adjList.value = Array(vertexCount.value).fill().map(() => [])
  
  // 重置树状态
  flattenedTreeNodes.value = []
  treeConnections.value = []
  treeContainerWidth.value = 300
  treeContainerHeight.value = 300
  
  // 关闭所有对话框
  addEdgeDialogVisible.value = false
}

// 初始化组件时准备数据
const initializeComponent = () => {
  console.log('Initializing component for type:', props.type)
  
  // 首先清空所有状态
  resetAllStates()
  
  // 确保所有数组已正确初始化
  ensureArraysInitialized()
  
  // 根据类型初始化不同的数据结构
  if (props.type === 'array' || props.type === 'linkedList') {
    elements.value = [1, 2, 3, 4, 5]
  } else if (props.type === 'binaryTree' || props.type === 'heap') {
    elements.value = [1, 2, 3, 4, 5, 6, 7]
    nextTick(() => {
      try {
        updateTreeLayout()
      } catch (e) {
        console.error('Error updating tree layout:', e)
      }
    })
  } else if (props.type === 'stack' || props.type === 'queue') {
    elements.value = [1, 2, 3]
  } else if (props.type === 'adjacencyMatrix') {
    initMatrix()
  } else if (props.type === 'adjacencyList') {
    initAdjList()
  }
}

const focusInput = (row, col) => {
  if (!isDirected.value && row === col) return
  const index = row * vertexCount.value + col
  nextTick(() => {
    if (matrixInputs.value[index]) {
      matrixInputs.value[index].focus()
    }
  })
}

// 更新树的布局和连接线
const updateTreeLayout = () => {
  if (props.type !== 'binaryTree' || !elements.value.length) return
  
  try {
    flattenedTreeNodes.value = []
    treeConnections.value = []
    
    // 计算树的深度
    const depth = Math.ceil(Math.log2(elements.value.length + 1))
    
    // 计算容器尺寸
    const containerWidth = Math.pow(2, depth - 1) * (NODE_SIZE + HORIZONTAL_SPACING)
    const containerHeight = depth * (NODE_SIZE + LEVEL_GAP)
    
    treeContainerWidth.value = Math.max(300, containerWidth)
    treeContainerHeight.value = Math.max(200, containerHeight)
    
    // 创建节点位置
    for (let i = 0; i < elements.value.length; i++) {
      const level = Math.floor(Math.log2(i + 1))
      const position = i + 1 - Math.pow(2, level)
      const totalNodesInLevel = Math.pow(2, level)
      const levelWidth = treeContainerWidth.value
      
      // 水平位置计算
      const spacing = levelWidth / (totalNodesInLevel + 1)
      const x = spacing * (position + 1)
      
      // 垂直位置计算
      const y = level * (NODE_SIZE + LEVEL_GAP) + NODE_SIZE / 2
      
      flattenedTreeNodes.value.push({
        index: i,
        value: elements.value[i],
        x,
        y
      })
      
      // 添加父子连接线
      if (i > 0) {
        const parentIndex = Math.floor((i - 1) / 2)
        if (parentIndex >= 0 && 
            flattenedTreeNodes.value[parentIndex] && 
            elements.value[i] !== null) {
          const parent = flattenedTreeNodes.value[parentIndex]
          treeConnections.value.push(`M${parent.x},${parent.y} L${x},${y}`)
        }
      }
    }
  } catch (e) {
    console.error('Error in updateTreeLayout:', e)
  }
}

// 监听元素变化，更新树的布局
watch(() => elements.value, updateTreeLayout, { deep: true })
watch(() => props.type, updateTreeLayout)

// 方法
const addElement = () => {
  if (!canAdd.value) {
    ElMessage.warning('已达到最大容量')
    return
  }

  const value = Math.floor(Math.random() * 100)
  elements.value.push(value)
  
  // 高亮新添加的元素
  const newIndex = elements.value.length - 1
  highlightElement(newIndex)
}

const removeElement = () => {
  if (!canRemove.value) {
    ElMessage.warning('没有元素可删除')
    return
  }

  // 高亮要删除的元素
  const index = elements.value.length - 1
  highlightElement(index)
  
  setTimeout(() => {
    elements.value.pop()
  }, 500)
}

const reset = () => {
  elements.value = []
  highlightedIndices.value = []
}

const highlightElement = (index) => {
  highlightedIndices.value = [index]
  setTimeout(() => {
    highlightedIndices.value = []
  }, 1000)
}

// 初始化矩阵
const initMatrix = () => {
  console.log('Initializing matrix...')
  // 创建新的矩阵数组以确保响应式
  const newMatrix = Array(vertexCount.value).fill(null).map(() => 
    Array(vertexCount.value).fill(0)
  )
  matrix.value = newMatrix
  
  // 清空高亮
  highlightedVertices.value = []
  highlightedEdges.value = []
  highlightedCells.value = []
  
  // 更新图形视图
  nextTick(() => {
    updateGraphView()
  })
}

// 初始化邻接表
const initAdjList = () => {
  console.log('Initializing adjacency list...')
  // 创建新的邻接表数组
  const newAdjList = Array(vertexCount.value).fill(null).map(() => [])
  adjList.value = newAdjList
  
  // 清空高亮
  highlightedVertices.value = []
  highlightedEdges.value = []
  
  console.log('Initialized adjacency list:', JSON.stringify(adjList.value))
  
  // 延迟更新图形视图以确保数据已准备好
  nextTick(() => {
    updateGraphView()
  })
}

// 更新图形视图
const updateGraphView = () => {
  console.log('Updating graph view for', props.type)
  // 创建新的边数组以确保响应式更新
  const newEdges = []
  
  if (props.type === 'adjacencyMatrix' && matrix.value && matrix.value.length > 0) {
    // 从邻接矩阵生成边
    for (let i = 0; i < vertexCount.value && i < matrix.value.length; i++) {
      for (let j = 0; j < vertexCount.value && j < matrix.value[i].length; j++) {
        if (matrix.value[i][j] === 1) {
          // 计算边的起点和终点坐标
          const angle1 = 2 * Math.PI * i / vertexCount.value - Math.PI/2
          const angle2 = 2 * Math.PI * j / vertexCount.value - Math.PI/2
          
          const x1 = Math.cos(angle1) * 120 + 150
          const y1 = Math.sin(angle1) * 120 + 150
          const x2 = Math.cos(angle2) * 120 + 150
          const y2 = Math.sin(angle2) * 120 + 150
          
          // 添加新边
          newEdges.push({
            from: i,
            to: j,
            x1, y1, x2, y2,
            isLoop: i === j,
            weight: 1
          })
        }
      }
    }
  } else if (props.type === 'adjacencyList' && adjList.value && adjList.value.length > 0) {
    // 从邻接表生成边
    for (let i = 0; i < vertexCount.value && i < adjList.value.length; i++) {
      if (Array.isArray(adjList.value[i])) {
        for (const edge of adjList.value[i]) {
          if (typeof edge === 'object' && edge !== null && 'vertex' in edge) {
            const j = edge.vertex
            const weight = isWeighted.value && 'weight' in edge ? edge.weight : 1
            
            if (j >= 0 && j < vertexCount.value) {
              // 计算边的起点和终点坐标
              const angle1 = 2 * Math.PI * i / vertexCount.value - Math.PI/2
              const angle2 = 2 * Math.PI * j / vertexCount.value - Math.PI/2
              
              const x1 = Math.cos(angle1) * 120 + 150
              const y1 = Math.sin(angle1) * 120 + 150
              const x2 = Math.cos(angle2) * 120 + 150
              const y2 = Math.sin(angle2) * 120 + 150
              
              // 检查是否为自环
              const isLoop = i === j
              
              if (isLoop) {
                // 自环使用路径
                const cx = x1 - 30  // 控制点x
                const cy = y1 - 30  // 控制点y
                newEdges.push({
                  from: i,
                  to: j,
                  x1, y1, x2, y2,
                  isLoop: true,
                  path: `M${x1},${y1} Q${cx},${cy} ${x2},${y2}`,
                  weight
                })
              } else {
                // 普通边使用直线
                newEdges.push({
                  from: i,
                  to: j,
                  x1, y1, x2, y2,
                  isLoop: false,
                  weight
                })
              }
            }
          }
        }
      }
    }
  }
  
  // 一次性更新边数组以确保响应式
  edges.value = newEdges
  console.log('Edges after update:', edges.value.length)
}

// 添加边
const addEdge = () => {
  console.log('Adding edge:', newEdge.value)
  
  // 如果是无向图且尝试添加自环，阻止操作
  if (!isDirected.value && newEdge.value.from === newEdge.value.to) {
    ElMessage.warning('无向图不支持自环')
    return
  }

  // 检查边是否已存在
  const edgeExists = adjList.value[newEdge.value.from].some(edge => edge.vertex === newEdge.value.to)
  if (edgeExists) {
    ElMessage.warning('边已存在')
    addEdgeDialogVisible.value = false
    return
  }
  
  // 添加边
  const weight = isWeighted.value ? newEdge.value.weight : 1
  
  // 创建新的邻接表来触发响应式更新
  const newAdjList = JSON.parse(JSON.stringify(adjList.value))
  
  // 确保数组索引存在
  if (!newAdjList[newEdge.value.from]) {
    newAdjList[newEdge.value.from] = []
  }
  
  // 添加新边
  newAdjList[newEdge.value.from].push({ 
    vertex: newEdge.value.to, 
    weight 
  })
  
  // 如果是无向图，同时更新对称位置
  if (!isDirected.value && newEdge.value.from !== newEdge.value.to) {
    if (!newAdjList[newEdge.value.to]) {
      newAdjList[newEdge.value.to] = []
    }
    newAdjList[newEdge.value.to].push({ 
      vertex: newEdge.value.from, 
      weight 
    })
  }
  
  // 更新邻接表
  adjList.value = newAdjList
  
  // 高亮新添加的边
  highlightedVertices.value = [newEdge.value.from, newEdge.value.to]
  
  console.log('Updated adjacency list:', JSON.stringify(adjList.value))
  
  // 立即更新图形视图
  nextTick(() => {
    updateGraphView()
  })
  
  // 短暂高亮，然后取消
  setTimeout(() => {
    highlightedVertices.value = []
    highlightedEdges.value = []
  }, 1000)
  
  addEdgeDialogVisible.value = false
}

// 切换边的存在
const toggleEdge = (row, col) => {
  console.log(`Toggling edge from ${row} to ${col}`)
  
  // 如果是无向图的对角线，不允许操作
  if (!isDirected.value && row === col) {
    return
  }
  
  // 创建矩阵的深拷贝
  const newMatrix = matrix.value.map(row => [...row])
  
  // 切换值（0变1，1变0）
  newMatrix[row][col] = newMatrix[row][col] === 0 ? 1 : 0
  
  // 如果是无向图，同步更新对称位置
  if (!isDirected.value && row !== col) {
    newMatrix[col][row] = newMatrix[row][col]
  }
  
  // 更新矩阵
  matrix.value = newMatrix
  
  // 高亮相关单元格和顶点
  highlightedCells.value = [`${row}-${col}`]
  if (!isDirected.value && row !== col) {
    highlightedCells.value.push(`${col}-${row}`)
  }
  highlightedVertices.value = [row, col]
  
  console.log('Matrix after toggle:', JSON.stringify(newMatrix))
  
  // 更新图形视图
  updateGraphView()
  
  // 短暂高亮后清除
  setTimeout(() => {
    highlightedCells.value = []
    highlightedVertices.value = []
  }, 1000)
}

// 更新邻接矩阵的类型（有向/无向，带权/无权）
const updateMatrixType = () => {
  // 如果从有向图切换到无向图，确保矩阵是对称的
  if (!isDirected.value) {
    for (let i = 0; i < vertexCount.value; i++) {
      for (let j = i + 1; j < vertexCount.value; j++) {
        if (matrix.value[i][j] !== matrix.value[j][i]) {
          // 取两个值中的最大值作为边的权重
          const maxWeight = Math.max(matrix.value[i][j], matrix.value[j][i])
          matrix.value[i][j] = maxWeight
          matrix.value[j][i] = maxWeight
        }
      }
      // 移除自环
      matrix.value[i][i] = 0
    }
  }
  
  // 如果切换了权重，更新权重
  if (!isWeighted.value) {
    // 所有非零值变为1
    for (let i = 0; i < vertexCount.value; i++) {
      for (let j = 0; j < vertexCount.value; j++) {
        if (matrix.value[i][j] !== 0) {
          matrix.value[i][j] = 1
        }
      }
    }
  }
  
  // 更新图形视图
  updateGraphView()
}

// 更新邻接表的类型（有向/无向，带权/无权）
const updateListType = () => {
  if (!adjList.value.length) return // 防止在初始化前调用
  
  // 将邻接表转换为邻接矩阵
  const tempMatrix = Array(vertexCount.value).fill().map(() => Array(vertexCount.value).fill(0))
  
  for (let i = 0; i < adjList.value.length; i++) {
    for (let edge of adjList.value[i]) {
      tempMatrix[i][edge.vertex] = edge.weight
    }
  }
  
  // 使用邻接矩阵的更新逻辑
  if (!isDirected.value) {
    for (let i = 0; i < vertexCount.value; i++) {
      for (let j = i + 1; j < vertexCount.value; j++) {
        if (tempMatrix[i][j] !== tempMatrix[j][i]) {
          const maxWeight = Math.max(tempMatrix[i][j], tempMatrix[j][i])
          tempMatrix[i][j] = maxWeight
          tempMatrix[j][i] = maxWeight
        }
      }
      // 移除自环
      tempMatrix[i][i] = 0
    }
  }
  
  if (!isWeighted.value) {
    for (let i = 0; i < vertexCount.value; i++) {
      for (let j = 0; j < vertexCount.value; j++) {
        if (tempMatrix[i][j] !== 0) {
          tempMatrix[i][j] = 1
        }
      }
    }
  }
  
  // 将更新后的邻接矩阵转回邻接表
  const newAdjList = Array(vertexCount.value).fill(null).map(() => [])
  for (let i = 0; i < vertexCount.value; i++) {
    for (let j = 0; j < vertexCount.value; j++) {
      if (tempMatrix[i][j] !== 0) {
        newAdjList[i].push({ vertex: j, weight: tempMatrix[i][j] })
      }
    }
  }
  adjList.value = newAdjList
  
  // 更新图形视图
  updateGraphView()
}

// 获取邻接表中边的索引
const getEdgeIndexFromAdjList = (from, to) => {
  return edges.value.findIndex(edge => 
    (edge.from === from && edge.to === to) || 
    (!isDirected.value && edge.from === to && edge.to === from)
  )
}

// 切换邻接表中的边
const toggleAdjListEdge = (from, to) => {
  // 如果是无向图且尝试添加自环，阻止操作
  if (!isDirected.value && from === to) {
    ElMessage.warning('无向图不支持自环')
    return
  }
  
  // 找到边的索引
  const edgeIndex = adjList.value[from].findIndex(edge => edge.vertex === to)
  
  if (edgeIndex === -1) {
    // 添加边
    const weight = isWeighted.value ? Math.floor(Math.random() * 9) + 1 : 1
    adjList.value[from].push({ vertex: to, weight })
    
    // 如果是无向图，同时更新对称位置
    if (!isDirected.value && from !== to) {
      adjList.value[to].push({ vertex: from, weight })
    }
    
    // 高亮新添加的边
    highlightedVertices.value = [from, to]
  } else {
    // 边存在，删除边
    adjList.value[from].splice(edgeIndex, 1)
    
    // 如果是无向图，同时更新对称位置
    if (!isDirected.value && from !== to) {
      const reverseEdgeIndex = adjList.value[to].findIndex(edge => edge.vertex === from)
      if (reverseEdgeIndex !== -1) {
        adjList.value[to].splice(reverseEdgeIndex, 1)
      }
    }
  }
  
  // 更新图形视图
  updateGraphView()
  
  // 短暂高亮，然后取消
  setTimeout(() => {
    highlightedVertices.value = []
    highlightedEdges.value = []
  }, 1000)
}

// 显示添加边对话框
const showAddEdgeDialog = (fromVertex) => {
  newEdge.value = {
    from: fromVertex,
    to: 0,
    weight: isWeighted.value ? Math.floor(Math.random() * 9) + 1 : 1
  }
  addEdgeDialogVisible.value = true
}

// 监听type属性变化，确保组件被重新打开时正确初始化
watch(() => props.type, (newType, oldType) => {
  console.log(`Type changed from ${oldType} to ${newType}`)
  
  // 先重置所有状态
  resetAllStates()
  
  // 延迟初始化，确保DOM已更新
  nextTick(() => {
    try {
      initializeComponent()
    } catch (e) {
      console.error('Error initializing component:', e)
    }
  })
}, { immediate: true })

// 监听vertexCount的变化
watch(vertexCount, (newCount) => {
  if (props.type === 'adjacencyMatrix') {
    // 保持现有的边，调整矩阵大小
    const newMatrix = Array(newCount).fill(null).map((_, i) => {
      const row = Array(newCount).fill(0)
      if (i < matrix.value.length) {
        // 复制现有的边
        for (let j = 0; j < Math.min(newCount, matrix.value[i].length); j++) {
          row[j] = matrix.value[i][j]
        }
      }
      return row
    })
    matrix.value = newMatrix
    updateGraphView()
  } else if (props.type === 'adjacencyList') {
    // 保持现有的边，但调整数组大小
    const newList = Array(newCount).fill(null).map((_, i) => {
      if (i < adjList.value.length) {
        // 保留现有的边，但过滤掉指向不存在顶点的边
        return adjList.value[i].filter(edge => edge.vertex < newCount)
      }
      return []
    })
    adjList.value = newList
    updateGraphView()
  }
})

// 断开所有引用和监听器
const clearReferences = () => {
  console.log('Clearing all references')
  
  // 清空引用对象
  elements.value = null
  matrix.value = null
  adjList.value = null
  edges.value = null
  highlightedIndices.value = null
  highlightedVertices.value = null
  highlightedEdges.value = null
  highlightedCells.value = null
  flattenedTreeNodes.value = null
  treeConnections.value = null
  
  // 设置尺寸为0
  treeContainerWidth.value = 0
  treeContainerHeight.value = 0
}

// 组件卸载前清理资源
onBeforeUnmount(() => {
  try {
    resetAllStates()
    clearReferences()
    console.log('Component unmounted, all states reset and references cleared')
  } catch (e) {
    console.error('Error during component cleanup:', e)
  }
})

// 生命周期钩子
onMounted(() => {
  console.log('Component mounted')
  
  // 确保所有数组已正确初始化
  ensureArraysInitialized()
  
  // 延迟初始化，确保DOM已更新
  nextTick(() => {
    try {
      initializeComponent()
    } catch (e) {
      console.error('Error initializing component on mount:', e)
    }
  })
})
</script>

<style scoped>
.data-structure-visualizer {
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.visualization-container {
  min-height: 300px;
  padding: 20px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

/* 数组可视化样式 */
.array-visualization {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.array-elements {
  display: flex;
  gap: 4px;
}

.array-element {
  width: 50px;
  height: 50px;
  border: 2px solid #409eff;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: all 0.3s;
}

.element-value {
  height: 35px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
}

.element-index {
  height: 15px;
  font-size: 12px;
  color: #909399;
}

/* 链表可视化样式 */
.linked-list-visualization {
  display: flex;
  justify-content: center;
}

.list-elements {
  display: flex;
  align-items: center;
  gap: 20px;
}

.list-node {
  display: flex;
  align-items: center;
}

.node-value {
  width: 50px;
  height: 50px;
  border: 2px solid #409eff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.node-pointer {
  margin: 0 10px;
  color: #409eff;
  font-size: 20px;
}

/* 二叉树可视化样式 */
.binary-tree-visualization {
  display: flex;
  justify-content: center;
  padding: 20px;
  overflow: auto;
  width: 100%;
  height: 100%;
}

.tree-container {
  position: relative;
  min-height: 300px;
  min-width: 300px;
  margin: 0 auto;
}

.tree-connections {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  pointer-events: none;
}

.tree-node {
  position: absolute;
  width: 40px;
  height: 40px;
  border: 2px solid #409eff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  background-color: white;
  transition: all 0.3s;
  z-index: 2;
}

.tree-node.empty-node {
  border-color: transparent;
}

.tree-node.highlight {
  background-color: #ecf5ff;
  border-color: #409eff;
  transform: scale(1.1);
  z-index: 3;
}

/* 栈可视化样式 */
.stack-visualization {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stack-elements {
  display: flex;
  flex-direction: column-reverse;
  gap: 4px;
  border: 2px solid #409eff;
  padding: 10px;
  min-height: 200px;
}

.stack-element {
  width: 100px;
  height: 40px;
  border: 1px solid #409eff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.stack-pointer {
  margin-top: 10px;
  color: #409eff;
  font-weight: bold;
}

/* 队列可视化样式 */
.queue-visualization {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.queue-elements {
  display: flex;
  gap: 4px;
  border: 2px solid #409eff;
  padding: 10px;
  min-width: 300px;
}

.queue-element {
  width: 50px;
  height: 50px;
  border: 1px solid #409eff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.queue-pointers {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: 10px;
  color: #409eff;
  font-weight: bold;
}

/* 高亮效果 */
.highlight {
  background-color: #ecf5ff;
  border-color: #409eff;
  transform: scale(1.1);
}

/* 响应式布局 */
@media (max-width: 768px) {
  .visualization-container {
    padding: 10px;
  }

  .array-element,
  .queue-element {
    width: 40px;
    height: 40px;
  }

  .stack-element {
    width: 80px;
    height: 30px;
  }
}

/* 邻接矩阵可视化样式 */
.matrix-visualization, .list-visualization {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.matrix-controls, .list-controls {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
  align-items: center;
}

.graph-view {
  display: flex;
  gap: 30px;
  width: 100%;
  justify-content: center;
  flex-wrap: wrap;
}

.vertex-container {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

.vertex {
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background-color: #409eff;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  transform: translate(-50%, -50%);
  transition: all 0.3s;
}

.vertex.highlight {
  background-color: #f56c6c;
  transform: translate(-50%, -50%) scale(1.2);
  z-index: 10;
}

.edges {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.edges line {
  transition: all 0.3s;
}

.edges line.highlighted-edge {
  stroke: #f56c6c;
  stroke-width: 3;
}

.matrix-container {
  min-width: 300px;
  overflow-x: auto;
}

.matrix-table {
  border-collapse: collapse;
  width: 100%;
}

.matrix-table th, .matrix-table td {
  border: 1px solid #ebeef5;
  padding: 8px;
  text-align: center;
  transition: all 0.3s;
}

.matrix-table th {
  background-color: #f5f7fa;
  font-weight: bold;
}

.matrix-table td {
  cursor: pointer;
}

.matrix-table td:hover:not(.diagonal) {
  background-color: #f5f7fa;
}

.matrix-table td.highlight {
  background-color: #ecf5ff;
}

.matrix-table td.diagonal {
  background-color: #f5f7fa;
  cursor: not-allowed;
}

.matrix-table td.has-value {
  color: #409eff;
  font-weight: bold;
}

/* 邻接表特有样式 */
.adj-list-container {
  min-width: 300px;
  max-width: 400px;
}

.adj-list-row {
  display: flex;
  margin-bottom: 10px;
  padding: 8px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  transition: all 0.3s;
}

.adj-list-row.highlight-row {
  background-color: #ecf5ff;
  border-color: #409eff;
}

.vertex-label {
  font-weight: bold;
  margin-right: 10px;
  min-width: 40px;
}

.adj-vertices {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.adj-vertex {
  padding: 4px 8px;
  background-color: #409eff;
  color: white;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

.adj-vertex:hover {
  background-color: #337ecc;
}

.adj-vertex.highlight {
  background-color: #f56c6c;
  transform: scale(1.1);
}

.empty-list {
  color: #909399;
  font-style: italic;
}

.help-text {
  text-align: center;
  color: #909399;
  margin-top: 10px;
  font-size: 12px;
  font-style: italic;
}

.matrix-table td {
  width: 40px;
  height: 40px;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  border: 1px solid #ebeef5;
  transition: all 0.3s;
}

.matrix-table td:hover:not(.diagonal) {
  background-color: #f5f7fa;
}

.matrix-table td.highlight {
  background-color: #ecf5ff;
}

.matrix-table td.diagonal {
  background-color: #f5f7fa;
  cursor: not-allowed;
}

.matrix-table td.has-value {
  color: #409eff;
  font-weight: bold;
}

.matrix-table td .el-input.is-disabled .el-input__inner {
  background-color: #f5f7fa !important;
  border-color: #e4e7ed !important;
  color: #909399 !important;
  cursor: not-allowed !important;
}
</style> 